package com.ruoyi.system.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.system.domain.DishMaterial;
import com.ruoyi.system.domain.Material;
import com.ruoyi.system.domain.dto.DishAddDTO;
import com.ruoyi.system.domain.dto.DishMaterialDTO;
import com.ruoyi.system.domain.dto.DishMaterialQtyDTO;
import com.ruoyi.system.domain.dto.DishUpdateDTO;
import com.ruoyi.system.domain.dto.MaterialAddDTO;
import com.ruoyi.system.domain.dto.MaterialUpdateDTO;
import com.ruoyi.system.domain.vo.DishMaterialVO;
import com.ruoyi.system.domain.vo.MaterialVO;
import com.ruoyi.system.mapper.DishMaterialMapper;
import com.ruoyi.system.mapper.MaterialMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.system.mapper.DishMapper;
import com.ruoyi.system.domain.Dish;
import com.ruoyi.system.service.IDishService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import static com.ruoyi.common.utils.SecurityUtils.getUsername;

/**
 * 菜品Service业务层处理
 *
 * @author ruoyi
 * @date 2025-03-22
 */
@Service
public class DishServiceImpl implements IDishService {
    @Autowired
    private DishMapper dishMapper;
    @Autowired
    private DishMaterialMapper dishMaterialMapper;
    @Autowired
    private MaterialMapper materialMapper;

    /**
     * 查询菜品
     *
     * @param id 菜品主键
     * @return 菜品
     */
    @Override
    public Dish selectDishById(String id) {
        return dishMapper.selectDishById(id);
    }


    /**
     * 查询菜品列表
     *
     * @param dish 菜品
     * @return 菜品
     */
    @Override
    public List<Dish> selectDishList(Dish dish) {
        return dishMapper.selectDishList(dish);
    }

    /**
     * 新增菜品
     *
     * @param dish 菜品
     * @return 结果
     */
    @Override
    public int insertDish(Dish dish) {
        return dishMapper.insertDish(dish);
    }

    @Override
    public int insertDishWithMaterial(DishAddDTO dto) {
        String operName = getUsername();
        //1.添加菜品信息
        Dish dish = new Dish();
        dish.setDishName(dto.getDishName());
        dish.setDescription(dto.getDescription());
        dishMapper.insertDishBatch(Arrays.asList(dish));
        //2.添加菜品配料关联关系
        if (!ObjectUtils.isEmpty(dto.getAddList())) {
            List<DishMaterial> dishMaterialList = new ArrayList<>();
            for (MaterialAddDTO addDTO : dto.getAddList()) {
                DishMaterial dishMaterial = new DishMaterial();
                dishMaterial.setDishId(dish.getId());
                dishMaterial.setMaterialId(addDTO.getMaterialId());
                dishMaterial.setQuantity(addDTO.getQuantity());
                dishMaterial.setCreatedBy(operName);
                dishMaterial.setUpdatedBy(operName);
                dishMaterialList.add(dishMaterial);
            }
            dishMaterialMapper.insertDishMaterialBatch(dishMaterialList);
        }
        return dish.getId();
    }

    /**
     * 修改菜品
     *
     * @param
     * @return 结果
     */
    @Override
    public int updateDish(Dish dish) {
        return dishMapper.updateDish(dish);
    }

    /**
     * 批量删除菜品
     *
     * @param ids 需要删除的菜品主键
     * @return 结果
     */
    @Override
    public int deleteDishByIds(String[] ids) {
        return dishMapper.deleteDishByIds(ids);
    }

    /**
     * 删除菜品信息
     *
     * @param id 菜品主键
     * @return 结果
     */
    @Override
    public int deleteDishById(String id) {
        return dishMapper.deleteDishById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void importDish(List<DishMaterialDTO> dishList, String operName) {
        if (ObjectUtils.isEmpty(dishList)) {
            {
                throw new ServiceException("导入菜品信息不能为空！");
            }
        }
        materialMapper.deleteAllMaterial();
        dishMapper.deleteAllDish();
        dishMaterialMapper.deleteAllDishMaterial();
        //1.保存菜品配料信息
        Map<String, List<DishMaterialDTO>> dishNameMap = dishList.stream().collect(Collectors.groupingBy(DishMaterialDTO::getDishName));
        Map<String, String> materialNameUnitMap = dishList.stream()
                .filter(e -> !ObjectUtils.isEmpty(e.getUnit()))
                .collect(Collectors.toMap(DishMaterialDTO::getMaterialName, DishMaterialDTO::getUnit, (v1, v2) -> v1));
        Map<String, String> materialNameCategoryMap = dishList.stream()
                .filter(e -> !ObjectUtils.isEmpty(e.getCategory()))
                .collect(Collectors.toMap(DishMaterialDTO::getMaterialName, DishMaterialDTO::getCategory, (v1, v2) -> v1));
        List<String> materialNameList = dishList.stream().map(DishMaterialDTO::getMaterialName).distinct().collect(Collectors.toList());

        List<Material> materialList = materialNameList.stream().map(e -> {
            String unit = materialNameUnitMap.getOrDefault(e, "");
            String category = materialNameCategoryMap.getOrDefault(e, "");
            Material material = new Material();
            material.setName(e);
            material.setCode(IdUtils.fastSimpleUUID());
            material.setUnit(unit);
            material.setCategory(category);
            material.setCreatedBy(operName);
            material.setUpdatedBy(operName);
            return material;
        }).collect(Collectors.toList());
        materialMapper.insertMaterialBatch(materialList);
        Map<String, Integer> materialNameIdMap = materialList.stream().collect(Collectors.toMap(Material::getName, Material::getId, (v1, v2) -> v1));
        //2.保存菜品信息
        List<Dish> dishAddList = dishList.stream().map(DishMaterialDTO::getDishName).distinct().collect(Collectors.toList())
                .stream().map(e -> {
                    Dish dish = new Dish();
                    dish.setDishName(e);
                    dish.setCreatedBy(operName);
                    dish.setUpdatedBy(operName);
                    return dish;
                }).distinct().collect(Collectors.toList());
        dishMapper.insertDishBatch(dishAddList);
        //3.保存菜品配料关联信息
        List<DishMaterial> dishMaterialList = new ArrayList<>();
        for (Dish dish : dishAddList) {
            String dishName = dish.getDishName();
            List<DishMaterialDTO> dishMaterialDTOList = dishNameMap.get(dishName);
            if (dishMaterialDTOList == null) {
                continue;
            }
            for (DishMaterialDTO dto : dishMaterialDTOList) {
                DishMaterial dishMaterial = new DishMaterial();
                dishMaterial.setDishId(dish.getId());
                Integer materialId = materialNameIdMap.get(dto.getMaterialName());
                if (materialId == null) {
                    continue;
                }
                dishMaterial.setMaterialId(materialId);
                dishMaterial.setQuantity(!ObjectUtils.isEmpty(dto.getQuantity()) ? new BigDecimal(dto.getQuantity()) : BigDecimal.ZERO);
                dishMaterial.setCreatedBy(operName);
                dishMaterial.setUpdatedBy(operName);
                dishMaterialList.add(dishMaterial);
            }
        }
        dishMaterialMapper.insertDishMaterialBatch(dishMaterialList);
    }

    @Override
    public DishMaterialVO getInfo(String id) {
        DishMaterialVO vo = new DishMaterialVO();

        Dish dish = this.selectDishById(id);
        vo.setId(dish.getId());
        vo.setDishName(dish.getDishName());
        vo.setDescription(dish.getDescription());

        List<MaterialVO> materials = dishMaterialMapper.selectDishMaterialList(id);
        vo.setMaterials(materials);
        return vo;
    }

    @Override
    public void updateDishMaterial(DishUpdateDTO dto) {
        Dish dish = new Dish();
        dish.setId(dto.getId());
        dish.setDishName(dto.getDishName());
        dish.setDescription(dto.getDescription());
        dishMapper.updateDish(dish);

        if (!ObjectUtils.isEmpty(dto.getDeleteList())) {
            dishMaterialMapper.deleteByDishAndMaterials(dto.getId(), dto.getDeleteList());
        }
        String username = getUsername();
        if (!ObjectUtils.isEmpty(dto.getAddList())) {
            List<DishMaterial> dishMaterialList = new ArrayList<>();
            for (MaterialAddDTO addDTO : dto.getAddList()) {
                DishMaterial dishMaterial = new DishMaterial();
                dishMaterial.setDishId(dish.getId());
                dishMaterial.setMaterialId(addDTO.getMaterialId());
                dishMaterial.setQuantity(addDTO.getQuantity());
                dishMaterial.setCreatedBy(username);
                dishMaterial.setUpdatedBy(username);
                dishMaterialList.add(dishMaterial);
            }
            dishMaterialMapper.insertDishMaterialBatch(dishMaterialList);
        }
        if (!ObjectUtils.isEmpty(dto.getUpdateList())) {
            List<DishMaterialQtyDTO> updateQtyList = new ArrayList<>();
            for (MaterialUpdateDTO updateDTO : dto.getUpdateList()) {
                DishMaterialQtyDTO dto1 = new DishMaterialQtyDTO();
                dto1.setDishId(dish.getId());
                dto1.setMaterialId(updateDTO.getMaterialId());
                dto1.setQuantity(updateDTO.getQuantity());
                updateQtyList.add(dto1);
            }
            dishMaterialMapper.updateQuantityBatch(updateQtyList);
        }
    }
}
